﻿namespace GoodAdmin.System;

/// <inheritdoc cref="ISysPositionService"/>
public class SysPositionService : DbRepository<SysPosition>, ISysPositionService, ITransient
{
    private readonly IRedisCacheManager _redisCacheManager;

    public SysPositionService(IRedisCacheManager redisCacheManager)
    {
        _redisCacheManager = redisCacheManager;
    }
    /// <inheritdoc/>
    public async Task AddPosition(PositionAddInput input)
    {
        await CheckInput(input,CommonConst.ACTION_INSERT);
        if (await InsertAsync(input))
            RefreshCache();
    }
    /// <inheritdoc/>
    public async Task UpdatePosition(PositionUpdateInput input)
    {
        await CheckInput(input, CommonConst.ACTION_UPDATE);
        var curPostion = (await GetPositionList()).FirstOrDefault(p => p.Id == input.Id);
        if (await InsertAsync(input))
        {
            RefreshCache();
            //如果修改名字，那么需要将所有使用该职位的用户缓存清除
            if(curPostion.Name != input.Name)
            {
                await RefreshUserCache(input.Id);
            }
        }            
    }

    /// <inheritdoc/>
    public async Task DeletePosition(List<BaseIdInput> input)
    {
        var idList = input.Select(x => x.Id).ToList();
        
        //判断是否有用户使用这些职位
        if (await Context.Queryable<SysUser>().AnyAsync(u => idList.Contains(u.PosId)))
        {
            throw Oops.Oh(PositionErrorCode.P004);
        }
        if (await DeleteAsync(it => idList.Contains(it.Id)))
            RefreshCache();
    }

    /// <inheritdoc/>
    public async Task<List<SysPosition>> GetPositionList()
    {
        string key = CacheConst.SysPosition;
        var positionList = _redisCacheManager.Get<List<SysPosition>>(key);
        if (positionList == null)
        {
            positionList = await GetListAsync();
            _redisCacheManager.Set(key, positionList);
        }
        return positionList;
    }

    /// <inheritdoc/>
    public async Task<SqlSugarPagedList<SysPosition>> GetPositionPageList(PositionPageInput input)
    {
        
        return await Context.Queryable<SysPosition>()
            .WhereIF(input.DataScope!=null,it=>input.DataScope.Contains(it.OrgId))
            .WhereIF(!string.IsNullOrWhiteSpace(input.Category),it=>it.Category==input.Category)
            .WhereIF(input.OrgId>0,it=>it.OrgId==input.OrgId)
            .OrderBy(it=>it.SortCode)
            .ToPagedListAsync(input.PageIndex, input.PageSize);
    }

    public async Task<List<SysPosition>> GetPositionList(PositionSelectorInput input)
    {
        var posList = await GetPositionList();
        posList= posList.WhereIf(input.DataScope != null, it => input.DataScope.Contains(it.OrgId))
            .Where(it => it.OrgId == input.OrgId)
            .ToList();
        return posList;
    }

    #region 私有方法

    /// <summary>
    /// 检查输入
    /// </summary>
    /// <param name="position"></param>
    /// <param name="action"></param>
    /// <returns></returns>
    private async Task CheckInput(SysPosition position,string action)
    {        
        var positionList = await GetPositionList();
        //当前组织下是否存在同名职位
        if (positionList.Any(p=>p.OrgId==position.OrgId && p.Name==position.Name && p.Id!=position.Id))
        {
            throw Oops.Bah(PositionErrorCode.P003);
        }
        //当前组织是否存在相同编码职位
        if (positionList.Any(p => p.OrgId == position.OrgId && p.Code == position.Code && p.Id != position.Id))
        {
            throw Oops.Bah(PositionErrorCode.P002);
        }
        if (action == CommonConst.ACTION_UPDATE)
        {
            var curPostion = positionList.FirstOrDefault(p => p.Id == position.Id);
            if (curPostion == null)
            {
                throw Oops.Bah(PositionErrorCode.P001);
            }

            //组织ID不同
            if (curPostion.OrgId != position.OrgId)
            {
                //判断下该职位有没有对应的用户
                if(await Context.Queryable<SysUser>().AnyAsync(u => u.PosId == position.Id))
                {
                    throw Oops.Oh(PositionErrorCode.P004);
                }
            }
            
        }
    }

    //检查数据范围权限    
    private void RefreshCache()
    {
        _redisCacheManager.Remove(CacheConst.SysPosition);
    }

    /// <summary>
    /// 删除用户缓存
    /// </summary>
    /// <param name="posId"></param>
    /// <returns></returns>
    private async Task RefreshUserCache(long posId)
    {
        var userList = await Context.Queryable<SysUser>().Where(u => u.PosId == posId).Select(u => u.Id.ToString()).ToArrayAsync();
        _redisCacheManager.HashDel<SysUser>(CacheConst.SysUser, userList);
    }
    #endregion
}